<template>
  <article class="cmp cmp-decode-batch">
    <div class="table-header" :style="thStyles">
      <table>
        <tbody>
          <tr>
            <th v-for="(v, i) in tableHeaders" :key="`th_${i}`" :style="{ width: v.width }">{{ v.label }}</th>
          </tr>
        </tbody>
      </table>
    </div>
    <div class="table-body" @drop.prevent="filesDrop" @dragover.prevent>
      <table ref="table">
        <tbody>
          <tr v-for="(v, i) in filesList" :key="`file_${i}`">
            <template v-for="(item, index) in tableHeaders">
              <td :style="{ width: item.width }" :key="`td_${i}_${index}`">
                <button v-if="item.value === 'action'" type="button" class="btn btn-link" @click="deleteFileItem(i)"
                  title="删除">
                  <i class="fa fa-close"></i>
                </button>
                <span v-else>{{ v[item.value] || '' }}</span>
              </td>
            </template>
          </tr>
          <tr v-if="filesList.length === 0" class="nodata-tr">
            <td>将待处理的文件拖动到此处</td>
          </tr>
        </tbody>
      </table>
    </div>
    <div class="btn-wrapper row">
      <div class="col col-6"><x-button type="default" block @click="clearFilesList">清 空</x-button></div>
      <div class="col col-6"><x-button type="primary" block @click="decode" :loading="loadingCount > 0">识 别</x-button>
      </div>
    </div>
    <div v-if="loadingCount > 0" class="mask">
      <x-loading></x-loading>
    </div>
  </article>
</template>

<script>
let QrScanner = global.QrScanner || null
let BarcodeReader = global.BarcodeReader || null
// let Quagga = global.Quagga || null

export default {
  name: 'cmp-decode-batch',
  props: {
    codeType: {
      type: String,
      default: 'qrcode'
    }
  },
  data() {
    return {
      filesList: [],
      tableHeaders: [
        { label: '文件路径', value: 'path', width: '30%' },
        { label: '解码结果', value: 'content', width: '50%' },
        { label: '状态', value: 'status', width: '10%' },
        { label: '操作', value: 'action', width: '10%' },
      ],
      thStyles: {},
      loadingCount: 0
    }
  },
  computed: {
    filePathsList() {
      return this.filesList.map(v => v.path)
    }
  },
  mounted() {
    this.init()
  },
  methods: {
    init() {
      BarcodeReader.Init()
      BarcodeReader.SetImageCallback((result) => {
        let index = this.loadingCount - 1
        if (result.length) {
          this.$set(this.filesList[index], 'content', (result[0] || {}).Value || '')
          this.$set(this.filesList[index], 'status', '成功')
        } else {
          this.$set(this.filesList[index], 'content', '')
          this.$set(this.filesList[index], 'status', '失败')
        }
        this.loadingCount--
        if (this.loadingCount > 0) {
          this.decodeBarcode()
        }
      })
    },
    // 拖拽待处理文件
    filesDrop(e) {
      const filesList = e.dataTransfer.files
      if (!filesList) return
      for (let i = 0; i < filesList.length; i++) {
        const file = filesList[i]
        if (!this.filePathsList.includes(file.path)) {
          this.filesList.push({
            file,
            path: file.path,
            content: '',
            status: '',
          })
        }
      }
      this.checkScroll()
    },
    // 解码
    decode() {
      this.filesList = this.filesList.map(v => {
        v.content = ''
        v.status = ''
        return v
      })
      if (this.codeType === 'barcode') {
        this.loadingCount = this.filesList.length
        this.decodeBarcode()
      } else {
        this.filesList.forEach((v, i) => {
          this.decodeQrcode(v.file, i)
        })
      }
    },
    // 二维码解码
    decodeQrcode(file, index) {
      this.$set(this.filesList[index], 'content', '')
      this.$set(this.filesList[index], 'status', '')
      this.loadingCount++
      QrScanner.scanImage(file).then(result => {
        this.$set(this.filesList[index], 'content', result)
        this.$set(this.filesList[index], 'status', '成功')
      }).catch(error => {
        console.log(error || 'No QR code found.')
        this.$set(this.filesList[index], 'content', '')
        this.$set(this.filesList[index], 'status', '失败')
      }).finally(() => {
        this.loadingCount--
      })
    },
    // 条形码解码
    decodeBarcode() {
      let index = this.loadingCount - 1
      let file = this.filesList[index]
      let img = new Image()
      img.onload = () => {
        BarcodeReader.DecodeImage(img)
      }
      img.onerror = () => {
        this.$set(this.filesList[index], 'content', '')
        this.$set(this.filesList[index], 'status', '失败')
        this.loadingCount--
        if (this.loadingCount > 0) {
          this.decodeBarcode()
        }
      }
      img.src = window.URL.createObjectURL(file.file)
      // this.$set(this.filesList[index], 'content', '')
      // this.$set(this.filesList[index], 'status', '')
      // Quagga.decodeSingle({
      //   src: window.URL.createObjectURL(file),
      //   numOfWorkers: navigator.hardwareConcurrency || 0, // Needs to be 0 when used within node
      //   decoder: {
      //     readers: ['code_128_reader', 'ean_reader', 'ean_8_reader', 'code_39_reader', 'code_39_vin_reader', 'codabar_reader', 'upc_reader', 'upc_e_reader', 'i2of5_reader', '2of5_reader', 'code_93_reader'] // List of active readers
      //   },
      // }, (result) => {
      //   console.log(result)
      //   if (result.codeResult) {
      //     this.$set(this.filesList[index], 'content', result.codeResult.code)
      //     this.$set(this.filesList[index], 'status', '成功')
      //   } else {
      //     this.$set(this.filesList[index], 'content', '')
      //     this.$set(this.filesList[index], 'status', '失败')
      //   }
      // })
    },
    // 删除条目
    deleteFileItem(index) {
      this.filesList.splice(index, 1)
      this.checkScroll()
    },
    checkScroll() {
      this.$nextTick(() => {
        if (!this.$refs.table) return
        let tableHeight = this.$refs.table.clientHeight
        let tableParentHeight = this.$refs.table.parentNode.clientHeight
        if (tableHeight > tableParentHeight) {
          this.thStyles = { overflow: 'hidden scroll' }
        } else {
          this.thStyles = { overflow: 'hidden' }
        }
      })
    },
    // 清空待处理文件
    clearFilesList() {
      this.filesList = []
      this.thStyles = {}
      this.loadingCount = 0
    },
  }
}
</script>

<style scoped lang="less">
@import "~@/assets/css/_mixins.less";
@import "~@/assets/css/_color.less";

.cmp-decode-batch {
  height: calc(100% - 3em - 64px);
  display: flex;
  flex-direction: column;
  position: relative;

  .table-header,
  .table-body {
    table {
      width: 100%;
      border: 1px solid @borderGrey;

      tr {
        height: 2em;
      }

      th,
      td {
        border: 1px solid @borderGrey;
        text-align: center;
        vertical-align: middle;
      }

      .nodata-tr {
        height: 100%;
        font-size: 16px;
        color: #999;
      }
    }
  }

  .table-body {
    height: calc(100% - 1em - 38px);
    overflow: auto;

    table {
      min-height: 100%;
    }
  }

  .btn-wrapper {
    margin-top: 1em;
  }

  .mask {
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
    border-radius: 8px;
    background-color: rgba(255, 255, 255, .5);
    .flex-center;
  }
}</style>
